﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityScriptEngine;

namespace MBBStoreClient
{
    public partial class frmChargedPaymentsEntry : Form
    {
        UnityProcessor proc = new UnityProcessor();
        UnityScript[] dat = new UnityScript[0];
        Threader t = new Threader();
        string _chargeInvoice = "";
        bool pamtErr = true;
        int typesel = -1;
        double addPayment = 0;
        string fID = "", fStamp = "";
        string _refNum = "";

        public frmChargedPaymentsEntry(string chargeInvoice, string refNum)
        {
            _chargeInvoice = chargeInvoice;
            _refNum = refNum;
            InitializeComponent();
            this.Load += new EventHandler(frmPaymentsEntry_Load);
            proc.ProcessError += new ProcessHandler(proc_ProcessError);
            proc.ProcessCompleted += new ProcessHandler(proc_ProcessCompleted);
            t.MethodCompleted += new EventHandler(t_MethodCompleted);
            txtType.SelectedIndexChanged += new EventHandler(txtType_SelectedIndexChanged);
            txtPaymentAmount.TextChanged += new EventHandler(txtPaymentAmount_TextChanged);
            btnAttach.Click += new EventHandler(btnAttach_Click);
        }
        void btnAttach_Click(object sender, EventArgs e)
        {
            if (!txtORNumber.Text.Equals(""))
            {
                float balance = float.Parse(txtBalance.Text), amount = float.Parse(txtPaymentAmount.Text), diff = 0f;
                diff = balance - amount;
                if (diff < 0)
                {
                    MessageBox.Show("The entered amount is greater than your balance.\r\nPlease check the Payment Amount value.", "Invalid Data", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                States(false);
                AttachPayment();
            }
        }
        void txtAmount_TextChanged(object sender, EventArgs e)
        {
            t.MethodCall(CheckEntry);
        }
        void txtPaymentAmount_TextChanged(object sender, EventArgs e)
        {
            t.MethodCall(CheckEntry);
        }
        void txtType_SelectedIndexChanged(object sender, EventArgs e)
        {
            typesel = txtType.SelectedIndex;
            if (txtType.SelectedIndex == 0)
                grpType.Enabled = false;
            else
                grpType.Enabled = true;
        }
        void frmPaymentsEntry_Load(object sender, EventArgs e)
        {
            txtORNumber.Focus();
            this.Text = "Payments Entry Charge Invoice #" + _chargeInvoice;
            txtType.SelectedIndex = 0;
            States(false);
            LoadData();
        }

        //UnityCalls
        void t_MethodCompleted(object sender, EventArgs e)
        {
            t.SafeCall(this, delegate
            {
                switch (sender.ToString())
                {
                    case "CheckEntry":
                        if (pamtErr)
                        {
                            txtPaymentAmount.ForeColor = Color.Red;
                            btnAttach.Enabled = false;
                        }
                        else
                        {
                            txtPaymentAmount.ForeColor = Color.Black;
                            btnAttach.Enabled = true;
                        }
                                                
                        break;
                }
            });
        }
        void proc_ProcessError(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                MessageBox.Show(desc);
            });
        }
        void proc_ProcessCompleted(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                switch (id)
                {
                    case "LOADINTEREST":
                        proc.DBPUX_Data_Fetch(out dat);
                        ComputeInterest();
                        
                        break;
                    case "LOAD":
                        proc.DBPUX_Data_Fetch(out dat);

                        ComputeAmounts();
                        FormatGrid();
                        break;
                    case "COMMITINTEREST":
                        LoadData();
                        break;
                    case "ATTACH":
                        addPayment = double.Parse(txtPaymentAmount.Text);
                        txtPaymentAmount.Text = "";
                        txtORNumber.Text = "";
                        txtBank.Text = "";
                        txtAccountName.Text = "";
                        txtCheckNumber.Text = "";
                        txtType.SelectedIndex = 0;
                        pamtErr = true;
                        CheckInterest();
                        
                        break;
                }
            });
        }

        //Operations
        void LoadData()
        {
            UnityScript u = new UnityScript("LOAD", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            u.Script_Add(Script.DBPUX_QUERY,
                string.Format("SELECT fID, fQty ,fUnitPrice, fStamp FROM tblsalesitem WHERE fInvoice='{0}'",
                _chargeInvoice));
            u.Script_Add(Script.DBPUX_QUERY,
                string.Format("SELECT fID, fDateReceived,fORNumber, fAmount, fPaymentMode, fBankName, fAccountName, fCheckNumber, fDueDate, fStamp FROM tblChargePayments WHERE fInvoiceNumber='{0}' ORDER BY fDateReceived DESC",
                _chargeInvoice));
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void FormatGrid()
        {
            grdItems.Columns[0].Width = (grdItems.Width * 20) / 100;
            grdItems.Columns[1].Width = (grdItems.Width * 30) / 100;
            grdItems.Columns[2].Width = (grdItems.Width * 30) / 100;
            txtORNumber.Focus();
        }
        void ComputeAmounts()
        {
            DataTable po = new DataTable(), pay = new DataTable();
            po.Columns.Add("Qty", typeof(float));
            po.Columns.Add("Price", typeof(float));
            po.Columns.Add("SubTotal", typeof(float));
            po.Columns["SubTotal"].Expression = "[Qty] * [Price]";

            float gtotal = 0f, ptotal = 0f, bal = 0f;
            for (int i = 0; i < dat[0].Data_Count; i++)
            {
                DataRow dr = po.NewRow();
                UnityElement e;
                dat[0].Data_Get(i, out e);
                dr["Qty"] = float.Parse(e.Data_GetField(0).ToString());
                dr["Price"] = float.Parse(e.Data_GetField(1).ToString());
                po.Rows.Add(dr);
                gtotal += float.Parse(po.Rows[i]["SubTotal"].ToString());
            }
            txtCIAmount.Text = gtotal.ToString("#,#0.00");

            pay.Columns.Add("Date", typeof(DateTime));
            pay.Columns.Add("OR Number", typeof(string));
            pay.Columns.Add("Amount", typeof(float));
            pay.Columns.Add("Type", typeof(string));
            pay.Columns.Add("BankName", typeof(string));
            pay.Columns.Add("AccountName", typeof(string));
            pay.Columns.Add("AccountNumber", typeof(string));
            pay.Columns.Add("DueDate", typeof(DateTime));

            for (int i = 0; i < dat[1].Data_Count; i++)
            {
                DataRow dr = pay.NewRow();
                UnityElement e;
                dat[1].Data_Get(i, out e);
                dr["Date"] = DateTime.Parse(e.Data_GetField(0).ToString());
                dr["OR Number"] = e.Data_GetField(1).ToString();
                dr["Amount"] = float.Parse(e.Data_GetField(2).ToString());
                dr["Type"] = e.Data_GetField(3).ToString();
                dr["BankName"] = e.Data_GetField(4).ToString();
                dr["AccountName"] = e.Data_GetField(5).ToString();
                dr["AccountNumber"] = e.Data_GetField(6).ToString();
                if (e.Data_GetField(7).ToString() != "") dr["DueDate"] = DateTime.Parse(e.Data_GetField(7).ToString());
                
                pay.Rows.Add(dr);
                ptotal += float.Parse(pay.Rows[i]["Amount"].ToString());
            }
            grdItems.DataSource = pay;
            txtTotalPayment.Text = ptotal.ToString("#,#0.00");

            bal = gtotal - ptotal;
            txtBalance.Text = bal.ToString("#,#0.00");
            if (bal > 0)
            {
                grpPayment.Enabled = true;
                txtType_SelectedIndexChanged(null, null);
                txtBalance.ForeColor = Color.Red;
            }
            else
            {
                txtBalance.ForeColor = Color.Black;
                States(false);
            }

           

            grdItems.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            grdItems.Columns[2].DefaultCellStyle.Format = "#,#0.00";
            grdItems.Columns[2].DefaultCellStyle.Font = new Font(grdItems.Font, FontStyle.Bold);

        }
        void CheckEntry()
        {
            string payamt = txtPaymentAmount.Text;
            float fpayamt = 0f, famt = 0f;
            if (float.TryParse(payamt, out fpayamt))
            {
                pamtErr = false;
            }
            else
            {
                pamtErr = true;
            }

            
        }
        void AttachPayment()
        {
            UnityScript u = new UnityScript("ATTACH", 5);
            u.Script_Add(Script.DBPUX_BEGIN);
            if (typesel == 0)
            {
                u.Script_Add(Script.DBPUX_INSERT, "tblchargepayments(fRef, fAccountName, fInvoiceNumber, fDateReceived, fORNumber, fAmount, fPaymentMode)",
                    new string[]{
                        _refNum,
                        txtAccountName.Text,
                        _chargeInvoice,
                        txtReceiveDate.Text,
                        txtORNumber.Text,
                        txtPaymentAmount.Text,
                        txtType.Text
                    });
            }
            else
            {
                u.Script_Add(Script.DBPUX_INSERT, "tblchargepayments(fRef, fInvoiceNumber, fDateReceived, fORNumber, fAmount, fPaymentMode, fBankName, fAccountName, fCheckNumber, fDueDate)",
                    new string[]{
                        _refNum,
                        _chargeInvoice,
                        txtReceiveDate.Text,
                        txtORNumber.Text,
                        txtPaymentAmount.Text,
                        txtType.Text,
                        txtBank.Text,
                        txtAccountName.Text,
                        txtCheckNumber.Text,
                        txtDueDate.Text
                    });
            }
            u.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(u);
        }
        void States(bool s)
        {
            grpPayment.Enabled = s;
            grpType.Enabled = s;
            btnAttach.Enabled = s;
        }
        void CheckInterest()
        {
            UnityScript x = new UnityScript("LOADINTEREST", 7);
            x.Script_Add(Script.DBPUX_BEGIN);
            x.Script_Add(Script.DBPUX_QUERY,
                string.Format("SELECT * FROM tblchargebalance WHERE fInvoice='{0}' AND fStatus = '1'",
                _chargeInvoice));
            x.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(x);
        }
        void ComputeInterest()
        {
            UnityElement e;
            dat[0].Data_Get(0, out e);
            string percentage = e.Data_GetField(2).ToString();
            string terms = e.Data_GetField(3).ToString();
            string duedate = e.Data_GetField(4).ToString();
            string pdate = e.Data_GetField(5).ToString();
            double balance = double.Parse(txtCIAmount.Text) - double.Parse(txtTotalPayment.Text);
            double interest = 0;
            fID = e.Data_ID.ToString();
            fStamp = e.Data_Stamp;

            //add new charge balance
            DateTime oldDate, newDate, storeDate;
            oldDate = DateTime.Parse(duedate);
            newDate = DateTime.Parse(txtReceiveDate.Text);
            storeDate = oldDate;

            if (newDate > oldDate)
            {
                int cnt = newDate.Subtract(oldDate).Days;
                int termsVal = int.Parse(terms);
                if (termsVal == 0) termsVal = 1;

                if (cnt > termsVal)
                {
                    int l = cnt / termsVal;
                    double per = (l * double.Parse(percentage)) / 100;
                    interest = balance * per;

                    int additionalDays = (l+1) * termsVal;
                    storeDate = oldDate.AddDays(additionalDays);
                }
                else
                {
                    interest = balance * (double.Parse(percentage) / 100);
                    storeDate = oldDate.AddDays(termsVal);
                }
            }
            else
            {
                interest = 0;
            }


            while (proc.IsRunning)
            {
            }
            UnityScript x = new UnityScript("COMMITINTEREST", 5);
            x.Script_Add(Script.DBPUX_BEGIN);
            x.Script_Add(Script.DBPUX_UPDATE,
                    string.Format("tblchargebalance SET fStatus='0'"),
                    string.Format("(fID='{0}')AND(fStamp='{1}')", fID, fStamp));
            x.Script_Add(Script.DBPUX_INSERT, "tblchargebalance(fInvoice, fBalance, fPercentage, fTerms, fDueDates, fDate, fStatus)",
                    new string[]{
                    _chargeInvoice,
                    interest.ToString(),
                    percentage,
                    terms,
                    storeDate.ToShortDateString(),
                    pdate,
                    "1"
                    });
            x.Script_Add(Script.DBPUX_COMMIT);
            proc.Run(x);
        }
    }
}
